﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using WisPortal.Models;
using System.IO;
using System.Xml;
using System.Data;
using WisPortal.Data;
using WisPortal;

namespace WisPortal.Areas.Train
{
    public class BizDataController : BaseController
    {
        //
        // GET: /Train/BizData/

        public ActionResult Index()
        {
            return View();
        }

        /// <summary>
        /// 1.10 获得车组号
        /// </summary>
        /// <returns></returns>
        public ActionResult GetTrainNumbers()
        {
            XmlDocument doc = new XmlDocument();
            XmlNode objectsNode = doc.CreateElement("TrainNumnbers");

            DataSet ds = DB.GetDataSet(string.Format("SELECT * FROM TSX_TRAINNUMBER ORDER BY POSITION"));
            if (DB.HasData(ds))
            {
                DataMapping dm = new DataMapping(HttpContext);
                foreach (DataRow row in ds.Tables[0].Rows)
                {
                    XmlNode objNode = doc.CreateElement("TrainNumber");
                    dm.AddAttributeToNode(doc, objNode, "number", row["TRAINNUMBER"].ToString());
                    dm.AddAttributeToNode(doc, objNode, "id", row["ID"].ToString());
                    dm.AddAttributeToNode(doc, objNode, "position", row["POSITION"].ToString());
                    objectsNode.AppendChild(objNode);
                }
            }
            doc.AppendChild(objectsNode);
            return Content(JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented).Replace("\"@", "\""));
        }

        /// <summary>
        /// 返回待更新记录列表 1.11
        /// </summary>
        /// <param name="deviceId"></param>
        /// <returns></returns>
        public ContentResult Check_Update(string deviceId)
        {
            XmlDocument doc = new XmlDocument();
            XmlNode objectsNode = doc.CreateElement("Objects");
            
            DataSet dsUpdate = DB.GetDataSet(string.Format("SELECT TOP 2 [GUID] FROM [TSX_BIZDATA_YXJL] WHERE TRAINNUMBER = '{0}' AND (STATUS = 0 OR STATUS = 3) ORDER BY CREATEDTIME DESC",deviceId));
            if (DB.HasData(dsUpdate))
            {
                DataMapping dm = new DataMapping(HttpContext);
                foreach (DataRow row in dsUpdate.Tables[0].Rows)
                {
                    XmlNode objNode = doc.CreateElement("Object");
                    dm.AddAttributeToNode(doc,objNode,"dataId",row["GUID"].ToString());
                    objectsNode.AppendChild(objNode);
                }
            }
            //doc.Load(Server.MapPath("~/Areas/Train/Models/BizData/YXJL") + "\\DownloadList.xml");
            doc.AppendChild(objectsNode);
            return Content(JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented).Replace("\"@", "\""));
        }



        /// <summary>
        /// 返回具体的一条记录 1.12
        /// </summary>
        /// <remarks></remarks>
        /// <param name="dataId">待更新的数据ID</param>
        /// <returns></returns>
        [AllowAnonymous]
        public ActionResult Get_Update(string dataId)
        {
            string dmKey = "app.tsx.data.bizdata";

            XmlDocument doc = new XmlDocument();
            string table = "TSX_BIZDATA_YXJL";
            string idfield = "GUID"; 
                
            XmlDocument docDataMapping = XmlHelper.GetConfigration(dmKey);
            if (docDataMapping == null)
                return GetResult(CODE_ERROR_CONFIG, "未找到配置文件");
            else
            {
                DataMapping dm = new DataMapping(HttpContext);
                XmlNode objNode = GetObject(dm, doc, docDataMapping, table, idfield, dataId);
                if (objNode != null)
                {
                    //将数据添加到XmlDocument文档中并转换为JSON格式返回给客户端
                    doc.AppendChild(objNode);
                    return Content(JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented).Replace("\"@", "\""));
                }
                else
                    return GetResult(CODE_ERROR_NODATAFOUND, "获取数据记录失败");
            }
            
            
            //doc.Load(Server.MapPath("~/Areas/Train/Models/BizData/YXJL") + "\\DownloadDataItem.xml");
            //return Content(JsonConvert.SerializeXmlNode(doc, Newtonsoft.Json.Formatting.Indented));
        }

        /// <summary>
        /// 根据配置信息从数据库中取得一个数据的记录，并整理成为XML节点
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="configDoc"></param>
        /// <param name="table"></param>
        /// <param name="idfield"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        protected XmlNode GetObject(DataMapping dm, XmlDocument doc, XmlDocument configDoc, string table, string idfield, string id)
        {
            string sql = string.Format("SELECT * FROM {0} WHERE {1} = '{2}'", table, idfield, id);
            DataSet dsItem = DB.GetDataSet(sql);
            if (DB.HasData(dsItem) && configDoc != null)
            {
                DataRow item = dsItem.Tables[0].Rows[0];
                XmlNode objectsNode = doc.CreateElement("Objects");

                XmlNode objConfigNode = configDoc.SelectSingleNode(string.Format(".//Object[@table='{0}']",table));
                if (objConfigNode != null)
                {
                    XmlNode newObjNode = CreateObjectNode(doc, objConfigNode, dm,id,item);
                    objectsNode.AppendChild(newObjNode);
                }
                else
                    throw new CustomerException("无法找到名称为{0}的配置节点",table);
                return objectsNode;
            }
            else
                return null;
        }

        protected XmlNode CreateObjectNode(XmlDocument doc,XmlNode objConfigNode,DataMapping dm,string id,DataRow item)
        {
            XmlNodeList properties = objConfigNode.SelectNodes("Property");
            XmlNode newObjNode = doc.CreateElement("Object");
            //Add table property to object node.
            dm.AddAttributeToNode(doc, newObjNode, "table", XmlHelper.GetAttributeValue(objConfigNode, "table"));
            foreach (XmlNode prop in properties)
            {
                XmlNode propNode = doc.CreateElement("Property");
                if (XmlHelper.GetAttributeValue(prop, "type").Equals("object"))
                {
                    //Object node
                    string filed = XmlHelper.GetAttributeValue(prop, "name");
                    dm.AddAttributeToNode(doc, propNode, "name", filed);
                    XmlNode objectConfig = prop.SelectSingleNode("Object");
                    string sqlChild = string.Format("SELECT * FROM {0} WHERE {1} = '{2}'",
                        XmlHelper.GetAttributeValue(objectConfig, "table"),
                        XmlHelper.GetAttributeValue(objectConfig, "parent_key_field"),
                        id);
                    DataSet dsObjects = DB.GetDataSet(sqlChild);
                    //Get child objects
                    if (DB.HasData(dsObjects))
                    {
                        foreach (DataRow row in dsObjects.Tables[0].Rows)
                        {
                            XmlNode subObjNode = CreateObjectNode(doc, objectConfig, dm, id, row);
                            propNode.AppendChild(subObjNode);
                        }
                    }

                }
                else if (XmlHelper.GetAttributeValue(prop, "type").Equals("RelatedFile"))
                {
                    //Related file

                }
                else
                {
                    //Data types
                    string filed = XmlHelper.GetAttributeValue(prop, "field");
                    dm.AddAttributeToNode(doc, propNode, "field", filed);
                    propNode.InnerText = item[filed].ToString();
                }
                //Add property node to the object node
                newObjNode.AppendChild(propNode);
            }
            return newObjNode;
        }
        

        /// <summary>
        /// 客户端更新数据后，修改服务器端的数据状态 1.13
        /// </summary>
        /// <param name="dataId"></param>
        /// <param name="status"></param>
        /// <returns></returns>
        public JsonResult Set_Update_Status(string dataId, int status)
        {            
            string table = "TSX_BIZDATA_YXJL";
            string idfield = "GUID";

            string sql = string.Format("UPDATE {0} SET STATUS = {3} WHERE {1} = '{2}'",
                table,
                idfield,
                dataId,
                status);
            
            if (DB.ExecuteNonQuery(sql) > 0)
                return GetResult(CODE_SUCCESS, "操作成功");
            else
                return GetResult(CODE_ERROR_NODATAFOUND, "更新数据失败");                     
        }

        private static DataSet GetChangeRecord(string dataId)
        {
            return DB.GetDataSet(string.Format("SELECT * FROM TSX_RECORDCHANGE WHERE IDVALUE = '{0}'", dataId));
        }

        /// <summary>
        /// 上传需要更新的单条数据 1.51
        /// </summary>
        /// <param name="deviceId"></param>
        /// <param name="dataId"></param>
        /// <returns></returns>
        [ValidateInput(false)]
        public JsonResult Send_Update(string deviceId,string dataId)
        {
            //Get meta data of the record

            string time = DateTime.Now.ToString().Replace("/", "").Replace(" ", "").Replace("-", "").Replace(":", "");
            string uploadPath = Server.MapPath("~/UploadFile/Train/BizData/YXJL/");
            if (!Directory.Exists(uploadPath))
                Directory.CreateDirectory(uploadPath);
            StreamWriter sw = new StreamWriter(string.Format("{0}UploadData_{1}.log", uploadPath, time));
                
            //The Json content is involved in content field            
            CustomResult cr = new CustomResult();
            cr.Code = 0;
            cr.Description = "上传成功";
            if (Request["content"] == null)
            {
                cr.Code = 1;
                cr.Description = "缺少content字段";
            }
            else
            {
                string content = Request["content"];
                XmlDocument config = XmlHelper.GetConfigration("app.tsx.data.bizdata") ;
                //保存上传数据
                WisPortal.Data.DataMapping dm = new WisPortal.Data.DataMapping(null);
                try
                {
                    if (dm.UpdateData(content, config) == 0)
                    {
                        cr.Code = 2;
                        cr.Description = "数据更新失败";
                    }
                }
                catch (CustomerException ex)
                {
                    cr.Code = 3;
                    cr.Description = "数据更新异常";
                    Dictionary<string, string> kvs = new Dictionary<string, string>();
                    kvs.Add("message", ex.Message);
                    kvs.Add("description",ex.Description);
                    kvs.Add("trace", ex.StackTrace);
                    cr.Object = kvs;
                    sw.WriteLine(string.Format("CODE:{0},        DESCRIPTION:{1}",cr.Code, ex.Description));                
                }
                catch (Exception ex)
                {
                    cr.Code = 2;
                    cr.Description = "数据更新异常";
                    Dictionary<string, string> kvs = new Dictionary<string, string>();
                    kvs.Add("message", ex.Message);
                    kvs.Add("trace", ex.StackTrace);
                    cr.Object = kvs;
                    sw.WriteLine(string.Format("CODE:{0}, \r\n MESSAGE:{1} \r\n       DESCRIPTION:{2}", cr.Code,ex.Message, ex.StackTrace));
                }
                //保存上传图片
                sw.WriteLine(string.Format("dataId:{0}   deviceId:{1}", dataId, deviceId));
                sw.WriteLine(content);
                if (Request.Files.Count > 0)
                {
                    for (int i = 0; i < Request.Files.Count;i++ )
                    {
                        sw.WriteLine(string.Format("File{0}:{1}", i, Request.Files[i].FileName));
                        Request.Files[i].SaveAs(string.Format("{0}{1}_{2}_{3}", uploadPath, time, Guid.NewGuid().ToString(), Request.Files[i].FileName));
                    }
                }
                
            }
            sw.Flush();
            sw.Close();

            return Json(cr);
            
        }

        public FileResult Download(string fileId)
        {
            //根据ID寻找文件记录
            //返回文件数据
            return File(Server.MapPath("~/UploadFile/Train/BizData/YXJL/Test.jpg"), "image/jpg", "Test.jpg");
        }

        
    }
}
